package com.sc.nft.annotation;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.sc.nft.exception.GlobalRunTimeException;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Aspect
@Component
@Slf4j
public class AuthenticationInterceptor {

    @Resource
    private AuthenticationReadFile authenticationReadFile;

    @Around("@annotation(authentication)")
    @SneakyThrows
    public Object around(ProceedingJoinPoint joinPoint, Authentication authentication) {

        if (!authenticationReadFile.getOpen()) {
            return joinPoint.proceed();
        }
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();
        // 获取请求头密文
        String ciphertext = request.getHeader("ciphertext");
        if (StrUtil.isBlank(ciphertext)) {
            // 迷惑接口调用人,不让他们知道到底因为什么错了.
            throw new GlobalRunTimeException("请求失败");
        }
        Map map = requiredParameter(joinPoint);
        StringJoiner info = new StringJoiner("&");
        map.forEach((o, o2) -> {
            info.add(o + "=" + o2);
        });
        info.add("secretKey" + "=" + authenticationReadFile.getSecretKey());
        log.debug("加密前字符串:{}", info);
        String md5 = SecureUtil.md5(info.toString());
        log.debug("生成的md5:{}", md5);

        if (md5.equals(ciphertext)) {
            return joinPoint.proceed();
        } else {
            throw new GlobalRunTimeException("请求失败");
        }
    }




    public final List<String>list= Lists.newArrayList("rushBuyDTOs","firstPayDTOs");
    private Map requiredParameter(ProceedingJoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        Map<String, Object> paramMap = new TreeMap<>();
        // 遍历参数数组，将参数写入Map中
        for (Object arg : args) {
            JSONObject.parseObject(JSONObject.toJSONString(arg), Map.class).forEach((o, o2) -> {
                if (list.contains(o)) {
                    return;
                }
                if (o2 instanceof Collection) {
                    // 把集合从小到大排序
                    Collections.sort((List) o2);
                }
                paramMap.put(o.toString(), o2);
            });
        }
        return paramMap;
    }

}
